home *** CD-ROM | disk | FTP | other *** search
Text File | 1998-06-01 | 5.7 KB | 296 lines | [TEXT/CWIE] |
- /*
- File: LinkedList.cp
-
- Contains: A linked list
- Written by: Steve Sisak
- Copyright: © 1995 by Steve Sisak, all rights reserved.
- */
-
- #include "LinkedList.h"
- #include "ListLink.h"
- #include "LinkedListIterator.h"
- #include "Exceptions.h"
-
-
- #pragma segment Main
- //--------------------------------------------------------------------------------
- // Initialize all local variables
- // This method is in the segment Main so LinkedList's may be in static constructors
- LinkedList::LinkedList(ListLink* first, ListLink* last)
- {
- if (first == nil)
- first = last;
- if (last == nil)
- last = first;
-
- long count = 0;
- ListLink* link = first;
-
- while (link != nil) // Count the number of links passed in
- {
- link->SetLinkedList(this);
-
- count += 1;
-
- ListLink* next = link->GetNextLink();
-
- if (next == nil)
- {
- if (last == nil)
- {
- last = link;
- }
- else if (qDebug && last != link)
- {
- Debugger();
- }
- }
-
- link = next;
- }
-
- fFirstLink = first;
- fLastLink = last;
- fIteratorList = nil;
- fElementCount = count;
- }
-
-
- #pragma segment AppMain
- //--------------------------------------------------------------------------------
- LinkedList::~LinkedList()
- {
- RemoveAllLinks();
- }
-
-
- #pragma segment AppMain
- //--------------------------------------------------------------------------------
- ListLink* LinkedList::GetNthLink(long index)
- {
- LinkedListIterator iter(*this);
-
- if (index > 0)
- {
- if (index <= fElementCount) // Don't waste time
- {
- for (ListLink* link = iter.FirstLink(); link; link = iter.NextLink())
- {
- if (--index <= 0)
- {
- return link;
- }
- }
- }
- }
- else if (index < 0) // Negative is relative to last link
- {
- if (fElementCount + index >= 0)
- {
- for (ListLink* link = iter.LastLink(); link; link = iter.PrevLink())
- {
- if (++index >= 0)
- {
- return link;
- }
- }
- }
- }
-
- return nil;
- }
-
-
- #pragma segment Main
- //--------------------------------------------------------------------------------
- // This method is in the segment Main so LinkedList's may be in static constructors
- void LinkedList::AppendLink(ListLink& link)
- {
- InsertLink(link, fLastLink, nil);
- }
-
-
- #pragma segment Main
- //--------------------------------------------------------------------------------
- // This method is in the segment Main so LinkedList's may be in static constructors
- void LinkedList::PrependLink(ListLink& link)
- {
- InsertLink(link, nil, fLastLink);
- }
-
-
- #pragma segment Main
- //--------------------------------------------------------------------------------
- // This method is in the segment Main so LinkedList's may be in static constructors
- void LinkedList::InsertBefore(ListLink& link, ListLink& before)
- {
- InsertLink(link, before.GetPrevLink(), &before);
- }
-
-
- #pragma segment Main
- //--------------------------------------------------------------------------------
- // This method is in the segment Main so LinkedList's may be in static constructors
- void LinkedList::InsertAfter(ListLink& link, ListLink& after)
- {
- InsertLink(link, &after, after.GetNextLink());
- }
-
-
- #pragma segment AppMain
- //--------------------------------------------------------------------------------
- ListLink* LinkedList::RemoveFirstLink()
- {
- ListLink* link = fFirstLink;
-
- if (link)
- {
- RemoveLink(*link);
- }
-
- return link;
- }
-
-
- //--------------------------------------------------------------------------------
- ListLink* LinkedList::RemoveLastLink()
- {
- ListLink* link = fLastLink;
-
- if (link)
- {
- RemoveLink(*link);
- }
-
- return link;
- }
-
-
- //--------------------------------------------------------------------------------
- void LinkedList::RemoveAllLinks(void)
- {
- if (fIteratorList)
- fIteratorList->RemovingAllLinks();
-
- ListLink* link = fFirstLink;
-
- fFirstLink = nil;
- fLastLink = nil;
-
- while ( link != nil )
- {
- ListLink *next = link->GetNextLink();
-
- #if qDebug
- if (next)
- Assert(next->GetPrevLink() == link);
- #endif
- link->SetPrevLink(nil);
- link->SetNextLink(nil);
-
- link = next;
- }
- }
-
-
- //--------------------------------------------------------------------------------
- void LinkedList::RemoveLink(ListLink& link)
- {
- ListLink* next = link.GetNextLink();
- ListLink* prev = link.GetPrevLink();
-
- #if qDebug // Perform consistancy checks
- if (next)
- {
- Assert(next->GetPrevLink() == &link);
- }
- else
- {
- Assert(fLastLink = &link);
- }
-
- if (prev)
- {
- Assert(prev->GetNextLink() == &link);
- }
- else
- {
- Assert(fFirstLink = &link);
- }
- #endif
-
- if (fIteratorList)
- fIteratorList->RemovingLink(link);
-
- // Get the link out of the list
-
- if (next)
- next->SetPrevLink(prev);
- else
- fLastLink = prev;
-
- if (prev)
- prev->SetNextLink(next);
- else
- fFirstLink = next;
-
- fElementCount--;
-
- link.SetPrevLink(nil);
- link.SetNextLink(nil);
- }
-
- void LinkedList::LinkRemoved(ListLink& /*link*/)
- {
- fElementCount--;
- }
-
- void LinkedList::LinkInserted(ListLink& link)
- {
- fElementCount++;
-
- if (fIteratorList)
- {
- fIteratorList->LinkInserted(link);
- }
- }
-
- //--------------------------------------------------------------------------------
- // InsertLink - insert a link in the list
- // This method is in the segment Main so LinkedList's may be in static constructors
- //--------------------------------------------------------------------------------
- #pragma segment Main
-
- void LinkedList::InsertLink(
- ListLink& link, // the link we're inserting
- ListLink* after, // the link we're inserting after
- ListLink* before) // the link we're inserting before
- {
- #if qDebug // Perform consistancy checks
-
- Assert(link.GetPrevLink() == nil);
- Assert(link.GetNextLink() == nil);
-
- if (!before) // end of list, or empty
- {
- Assert(fLastLink == after);
- }
-
- if (!after) // Beginning of list, or empty
- {
- Assert(fFirstLink == before);
- }
- else if (before) // Middle of list
- {
- Assert(after == before->GetPrevLink());
- Assert(after->GetNextLink() == before);
- }
-
- #endif
-
- link.Link(after, before, this);
- }
-
- #pragma segment AppMain
-
-